/****************************************************
 * The SNIFFER DNS Header
 * -----------------------------
 *
 * C. Nunez 	(cnunez@stevens.edu)
 * W. Best		(wbest@stevens.edu)
 * K. Fuhrman 	(ktfuhrman@gmail.com)
 * M. DiAmore 	(mdiamore@gmail.com)
 *
 * Date Created:	15 April, 2010
 *
 * Description
 * -----------
 * Contains macros to extrapolate DNS information by way
 * of bit-level acrobatics mastery!
 *
 * For the two of you who actually read these comments:
 * ----------------------------------------------------
 * A DNS frame is composed of the following (in order):
 *		
 *		Query ID [QID] (16 bits):			16-bit integer that represents the query being presented.
 *		Operation bit [QR] (1 bit):			Specifies the type of frame being sent: Query or Response.
 ****************************************************/

#ifndef	_DNS_H
#define _DNS_H

//========================
//	Defines.
//========================

//Opcode
//-------
#define		DNS_STD_QRY		0
#define		DNS_INV_QRY		1
#define		DNS_STATUS_REQ	2

//Rcode
//-----
#define		DNS_QRY_GOOD	0
#define		DNS_QRY_ERR		1
#define		DNS_SERVER_FAIL 2
#define		DNS_NAME_ERR	3
#define		DNS_QRY_REJ		5
		

//============================
//	Macros
//============================

#define		DNS_FLAGS_QR(f)			(((f) >> 15) & 0x1)
#define		DNS_FLAGS_OPCODE(f)		(((f) >> 11) & 0xf)
#define		DNS_FLAGS_AA(f)			(((f) >> 10) & 0x1)
#define		DNS_FLAGS_TC(f)			(((f) >> 9) & 0x1)
#define		DNS_FLAGS_RD(f)			(((f) >> 8) & 0x1)
#define		DNS_FLAGS_RA(f)			(((f) >> 7) & 0x1)
#define		DNS_FLAGS_Z(f)			(((f) >> 4) & 0x7)
#define		DNS_FLAGS_RCODE(f)		(((f) & 0xf))


//--------------------------------
//	Typedefs
//--------------------------------
typedef unsigned short u_short;
typedef unsigned char u_char;

//========================
//	The struct.
//========================

struct sniffer_dnshdr	{
	
	//General frame info
	//------------------
	u_short	qid;
	u_short	flags;				//OPCODE,AA,TC,RD,RA,Z,Rcode
	u_short	qdcount;		
	u_short	ancount;
	u_short	nscount;
	u_short arcount;
	
	//TODO: Make query/response name stuff.
	//------------------------------------
	
	
	sniffer_dnshdr(const char *p)
	{
		qid			=	(( (p)[0] << 8 ) | (p)[1]); 		//QID
		flags		=	(( (p)[2] << 8 ) | (p)[3]); 		//RFLAGS
		qdcount		=	(( (p)[4] << 8 ) | (p)[5]); 		//QDCOUNT
		ancount		=	(( (p)[6] << 8 ) | (p)[7]); 		//ANCOUNT
		nscount		=	(( (p)[8] << 8 ) | (p)[9]); 		//NSCOUNT
		arcount		=	(( (p)[10] << 8) | (p)[11]); 		//ARCOUNT
	}
};


#endif	/* _DNS_H	*/
